/**
 * Project: complex.java
 * 
 * File Created at 2011-3-21
 * $Id: CompilerTest.java 137 2011-03-23 06:18:04Z ymkyve501@163.com $
 * 
 * Copyright 1999-2100 Alibaba.com Corporation Limited.
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * Alibaba Company. ("Confidential Information").  You shall not
 * disclose such Confidential Information and shall use it only in
 * accordance with the terms of the license agreement you entered into
 * with Alibaba.com.
 */
package complex.java.compiler;

import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Arrays;

import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;

/**
 * TODO Comment of CompilerTest
 * 
 * @author gaoliang
 * @date 2011-3-21
 */
public class CompilerTest {
    public static void main(String[] args) throws Exception {
        String source = "public class Main { public static void main(String[] args) {System.out.println(\"Hello World!\");} }";
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
        StringSourceJavaObject sourceObject = new CompilerTest.StringSourceJavaObject("Main",
                source);
        Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(sourceObject);
        CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects);
        boolean result = task.call();
        if (result) {
            System.out.println("编译成功。");
        }
    }

    static class StringSourceJavaObject extends SimpleJavaFileObject {

        private String content = null;

        public StringSourceJavaObject(String name, String content) throws URISyntaxException {
            super(URI.create("string:///" + name.replace('.', '/') + Kind.SOURCE.extension),
                    Kind.SOURCE);
            this.content = content;
        }

        public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
            return content;
        }
    }

    //    private static double calculate(String expr) throws Exception {
    //        String className = "CalculatorMain";
    //        String methodName = "calculate";
    //        String source = "class " + className + " { public static double " + methodName
    //                + "() { return " + expr + "; } }";
    //        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
    //        StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
    //        StringSourceJavaObject sourceObject = new CompilerTest.StringSourceJavaObject("Main",
    //                source);
    //        Iterable<? extends JavaFileObject> fileObjects = Arrays.asList(sourceObject);
    //        CompilationTask task = compiler.getTask(null, fileManager, null, null, null, fileObjects);
    //        boolean result = task.call();
    //        if (result) {
    //            ClassLoader loader = CompilerTest.class.getClassLoader();
    //            try {
    //                Class<?> clazz = Class.forName(className);
    //                Method method = clazz.getMethod(methodName, new Class<?>[] {});
    //                Object value = method.invoke(null, new Object[] {});
    //                return (Double) value;
    //            } catch (Exception e) {
    //                e.printStackTrace();
    //                throw new Exception("内部错误。");
    //            }
    //        } else {
    //            throw new Exception("错误的表达式。");
    //        }
    //    }
    //    
    //    private static void test ()throws Exception{
    //        URL[] urls = new URL[]{new URL("file:/D:/work2/own/complex/")};  
    //        URLClassLoader loader = new URLClassLoader(urls);  
    //        Class clas = loader.loadClass("CalculatorMain");  
    //        Method m = clas.getMethods()[0];  
    //        Object o = clas.newInstance();  
    //        m.invoke(o);  
    //    }
}
